package org.test4j.mock.processor.filer;

import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;
import org.test4j.mock.Stubs;
import org.test4j.mock.processor.MockProcessor;

import javax.lang.model.element.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import static org.test4j.mock.processor.filer.ClassNames.CN_Bean;
import static org.test4j.mock.processor.filer.ClassNames.CN_Configuration;

/**
 * 统一生成Stubs Fake Bean配置类
 *
 * @author darui.wu
 */
public class StubsBeanFiler {
    private final ClassName fullName;

    private final String suffix;

    private final List<String> stubs;

    public StubsBeanFiler(String fullName, String suffix, Collection<String> stubs) {
        this.fullName = ClassNames.getClassName(fullName);
        this.suffix = suffix;
        this.stubs = new ArrayList<>(stubs);
        Collections.sort(this.stubs);
    }

    public void writeFiler() {
        TypeSpec.Builder builder = TypeSpec.classBuilder(fullName.simpleName() + suffix)
            .addModifiers(Modifier.PUBLIC)
            .addAnnotation(CN_Configuration);
        for (String stub : this.stubs) {
            builder.addMethod(this.m_beanStub(stub));
        }
        JavaFile.Builder javaBuilder = JavaFile.builder(fullName.packageName(), builder.build());
        MockProcessor.writeFiler(javaBuilder.build());
    }

    private MethodSpec m_beanStub(String stub) {
        ClassName className = ClassNames.getClassName(stub);
        MethodSpec.Builder builder = MethodSpec.methodBuilder("new" + className.simpleName())
            .returns(className)
            .addModifiers(Modifier.PUBLIC)
            .addAnnotation(CN_Bean)
            .addStatement("return $T.fake($L.class)", Stubs.class, className.simpleName());
        return builder.build();
    }
}